#include "app_buffer.h"
#include "log/log.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

static pthread_mutex_t init_lock = PTHREAD_MUTEX_INITIALIZER;
Buffer *app_buffer_init(int size)
{
    //检查数据合法性
    if (size <= 0)
    {
        log_error("size is invalid");
        return NULL;
    }
    //初始化buffer结构体空间
    Buffer *buffer = malloc(sizeof(Buffer));
    if (buffer == NULL)
    {
        log_error("malloc failed");
        return NULL;
    }
    //初始化buffer的ptr属性
    buffer->ptr = malloc(size);
    if (buffer->ptr == NULL)
    {
        log_error("malloc failed");
        free(buffer);
        return NULL;
    }
    //初始化buffer的其他属性
    buffer->total_size = size;
    buffer->len = 0;
    buffer->offset = 0;
    //初始化buffer的锁
    buffer->lock = init_lock;
    return buffer;
}
void app_buffer_free(Buffer *buffer)
{
    //检查数据的合法性
    if (buffer == NULL)
    {
        log_error("buffer is NULL");
        return;
    }
    //释放buffer的ptr属性
    if (buffer->ptr != NULL)
    {
        free(buffer->ptr);
    }
    //销毁锁
    pthread_mutex_destroy(&buffer->lock);
    //释放buffer的结构体哦空间
    free(buffer);
    log_debug("buffer free");
}
int app_buffer_write(Buffer *buffer, char *data, int len)
{
    //检查数据合法性
    if (buffer == NULL || data == NULL || len <= 0)
    {
        log_error("buffer is NULL or data is NULL or len is invalid");
        return -1;
    }
    //加锁
    pthread_mutex_lock(&buffer->lock);
    //如果剩余空间不足，则返回错误
    if (buffer->len + len > buffer->total_size)
    {
        log_error("buffer is full");
        return -1;
    }
    //计算写入的起始位置
    int write_start = buffer->offset + buffer->len;
    //修改写入的起始位置
    if (write_start >= buffer->total_size)
    {
        write_start -= buffer->total_size;
    }
    //写入数据
    if (write_start + len <= buffer->total_size)
    {
        memcpy(buffer->ptr + write_start, data, len);
    }
    else//写两段
    {
        //计算第一段的长度
        int frist_len = buffer->total_size - write_start;
        //写入第一段
        memcpy(buffer->ptr + write_start, data, frist_len);
        //写入第二段
        memcpy(buffer->ptr, data + frist_len, len - frist_len);
    }
    //更新buffer的len属性
    buffer->len += len;
    //解锁
    pthread_mutex_unlock(&buffer->lock);
    log_debug("app_buffer_write len=%d, offset=%d, len=%d, ptr=%s", len,
              buffer->offset, buffer->len, buffer->ptr);

    return 0;
}
int app_buffer_read(Buffer *buffer, char *data, int len)
{
    //检查数据合法性
    if (buffer == NULL || data == NULL || len <= 0)
    {
        log_error("buffer is NULL or data is NULL or len is invalid");
        return -1;
    }
    //加锁
    pthread_mutex_lock(&buffer->lock);
    //如果buffer中数据不足，则返回错误
    if (len > buffer->len)
    {
        log_error("buffer is empty");
        return -1;
    }
    //读取数据
    if (buffer->offset + len <= buffer->total_size)
    {
        memcpy(data, buffer->ptr + buffer->offset, len);
        buffer->len -= len;
    }
    else//读两段
    {
        //计算第一段的长度
        int first_len = buffer->total_size - buffer->offset;
        //读取第一段
        memcpy(data, buffer->ptr + buffer->offset, first_len);
        //读取第二段
        memcpy(data + first_len, buffer->ptr, len - first_len);
        //更新buffer的offset属性
        buffer->offset = len - first_len;
    }
    //更性buffer的len属性
    buffer->len -= len;
    //解锁
    pthread_mutex_unlock(&buffer->lock);
    log_debug("app_buffer_write len=%d, offset=%d, len=%d, ptr=%s", len,
              buffer->offset, buffer->len, buffer->ptr);

    return 0;
}